ES Rollover Index

Elasticsearch的TTL已经在5.0之后废除,它的原理是定时标记过期数据,然后从index中删除并执行merge,这个操作的开销是很大的,这就是TTL被废除的原因。作为替代,5.0之后加入了Rollover API,我们可以基于这个功能在某种程度上实现TTL语法

Rollover API的原理与之前一篇文章实时场景中Elasticsearch冷热索引分离中提到了index拆分是一样的,即当index的大小或者有效期(当前时间-创建时间)超过一定阈值时,滚动创建一个新的index

Rollover API接受一个alias name和一个conditions列表作为参数。参数中的alias必须指向且只指向一个index。当index满足参数中指定的conditions中的任意一个时,ES会创建一个新的index并且将alias转而指向它,这里借用一张老图

alias

基本语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 创建一个名为logs-0000001的index,并赋予别名logs_write
PUT /logs-000001
{
"aliases": {
"logs_write": {}
}
}

# 当logs_write指向的index创建时间超过7天,或者documents大于等于1000个,或者包含的数据size超过5GB,则会创建一个新的index logs-0000002并将logs_write指向它,同时移除旧的index logs-0000001的别名
POST /logs_write/_rollover
{
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}

Response如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"acknowledged": true,
"shards_acknowledged": true,
"old_index": "logs-000001",
"new_index": "logs-000002",
"rolled_over": true,
"dry_run": false,
"conditions": {
"[max_age: 7d]": false,
"[max_docs: 1000]": true,
"[max_size: 5gb]": false,
}
}

rolled_over:index是否被滚动创建,即滚动条件是否满足
dry_run:是否是测试演练,即不真正执行
conditions:每个condition是否满足

命名新index

如果旧的index以-{number}结尾,比如logs-1,那么新的index将会沿袭旧的格式,并将结尾的number加1并自动填充0以保持数字长度为6,例如logs-000002,如果旧的index名字不以-{number}结尾,那么必须手动指定新的index名字

1
2
3
4
5
6
7
8
POST /my_alias/_rollover/my_new_index_name
{
"conditions": {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}

如果希望按日期来滚动生成并且命名index,那么可以使用ES提供的date math。Rollover API支持date math,但要求index必须以.{number}结尾,例如logstash-2016.02.03-1,无论日期是否相同,最后数字总会在滚动之后+1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 创建index并以当天日期命名,例如logs-2017.11.01-1
PUT /%3Clogs-%7Bnow%2Fd%7D-1%3E
{
"aliases": {
"logs_write": {}
}
}

# 写入一条记录
PUT logs_write/_doc/1
{
"message": "a dummy log"
}

# refresh以使该条记录立即生效
POST logs_write/_refresh

# 如果在当天执行以下请求,则滚动生成的新的index名称为logs-2017.11.01-000002,但如果是在第二天执行,则新的index名为logs-2017.11.02-000002
POST /logs_write/_rollover
{
"conditions": {
"max_docs": "1"
}
}

定义新index

我觉得按常理的话,滚动生成的新的index应该继承旧的index的mappings和settings,但实际上并不是,如果不指定的话,新的index会用ES默认的配置。当然你可以使用index templates或者在请求体中自定义配置,就和create index API一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
PUT /logs-000001
{
"aliases": {
"logs_write": {}
}
}

# 指定新的index的shards为2
POST /logs_write/_rollover
{
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
},
"settings": {
"index.number_of_shards": 2
}
}

调试

Rollover API支持dry_run模式,即只是检查条件是否满足,但并不真正执行新建index和重定向alias的操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
PUT /logs-000001
{
"aliases": {
"logs_write": {}
}
}

POST /logs_write/_rollover?dry_run
{
"conditions" : {
"max_age": "7d",
"max_docs": 1000,
"max_size": "5gb"
}
}